/*
 * Copyright 2010 Donny A. Wijaya
 *  
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */
package com.uberium.lazy.project;

import static com.uberium.lazy.generate.PatternConstants.VALID_NAME;
import static org.apache.commons.lang.StringUtils.isEmpty;

import java.util.HashMap;
import java.util.Map;

import com.uberium.lazy.generate.AbstractGenerator;
import com.uberium.lazy.generate.Source;

import static com.uberium.lazy.generate.PatternConstants.VALID_PARENT_NAME;
/**
 * The Projector class. A generator class to generate a Java web project.
 * 
 * @author Donny A. Wijaya
 * @version 0.0.9
 * @since April 2010
 */
public class Projector extends AbstractGenerator<ProjectMojo> {
	/** The parent token */
	private static final String PARENT_TOKEN = "#parent#";
	
	/** The name token */
	private static final String NAME_TOKEN = "#name#";
	
	/* (non-Javadoc)
	 * @see com.uberium.lazy.generate.Generator#execute(java.lang.Object)
	 */
	public void execute(ProjectMojo mojo) throws Exception {
		final Map<String, Object> models = new HashMap<String, Object>();
		final String key = mojo.getKey().toLowerCase();
		final String _package = mojo.getPackage();
		
		if (!isEmpty(mojo.getParent()) && !mojo.getParent().matches(VALID_PARENT_NAME))
			throw new Exception("Project parent's name must end with suffix: '-parent'");
		
		if (!isEmpty(mojo.getName()) && !mojo.getName().matches(VALID_NAME))
			throw new Exception("Project's name is invalid.");
			
		if (isEmpty(mojo.getType()))
			mojo.setType(retrieveDefaultType(key));
		
		String[] names = mojo.getName().split("-");
		mojo.setWildcard(names[names.length - 1]);
		
		final String type = mojo.getType().toLowerCase();

		addKeyValuePairToModels(models, key, mojo);

		Source source = null;

		for (String setting: retrieveSettings(key, type)) {
			source = createSource(_package, setting, false);
			source.setRootPackage(_package);
			
			// Add setting/source as key/value to Freemarker objects map
			addKeyValuePairToModels(models, setting, source);
		}
		
		// Write files using models
		bulkWrite(models);
		
		models.clear();
	}
	
	/**
	 * Pre-process Source Name (File/Directory name)
	 * 
	 * @param sourceName
	 * @param models
	 * @return
	 */
	@Override
	protected final String processSourceName(String sourceName, Map<String, Object> models) throws Exception {		
		final ProjectMojo mojo = (ProjectMojo) models.get("project");
		final String name = mojo.getName();
		final String parent = mojo.getParent();
		
		boolean hasNameToken = sourceName.contains(NAME_TOKEN);
		boolean hasParentToken = sourceName.contains(PARENT_TOKEN);
			
		if (hasNameToken || hasParentToken) {
			sourceName = sourceName.replace(NAME_TOKEN, name);
			
			if (!isEmpty(parent) && hasParentToken)
				sourceName = sourceName.replace(PARENT_TOKEN, parent.replace("-parent", ""));
			else if (isEmpty(parent) && hasParentToken)
				throw new Exception("Please define the 'parent'.");
		} else {
			String targetDir = (name != null)? name.trim() : "";
			targetDir = (targetDir.matches(VALID_NAME))? targetDir + "/" : targetDir;
			sourceName = targetDir + sourceName;
		}
		
		return sourceName.replace("//", "/");
	}
}